package bb.lanxing.device.thirdpart.gpx

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.view.View
import android.view.animation.TranslateAnimation
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import bb.lanxing.App
import bb.lanxing.R
import bb.lanxing.activity.login.AccountLoginActivity
import bb.lanxing.databinding.ActivityGpxImportBinding
import bb.lanxing.databinding.unit.AltitudeUnit
import bb.lanxing.databinding.unit.DistanceUnit
import bb.lanxing.databinding.utils.FormatterUtil
import bb.lanxing.mvvm.base.BaseDBActivity
import bb.lanxing.mvvm.base.viewmodel.ContextAction
import bb.lanxing.util.text.ToastHelper
import bb.lanxing.util.ui.DropDownItem
import bb.lanxing.util.ui.DropDownPopWindow
import com.github.mikephil.charting.utils.Utils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class GPXImportActivity : BaseDBActivity<ActivityGpxImportBinding>() {
    private var currentDropDownItem: DropDownItem? = null

    private val viewModel: GPXImportViewModel by viewModels()

    private val gpxPreviewMapFragment by lazy {
        GPXPreviewMapFragment()
    }

    override fun getLayoutId() = R.layout.activity_gpx_import

    override fun initView(t: ActivityGpxImportBinding) {
        setupActionBar(true)
        setTitle(R.string.st_import_gpx)
        if (!App.getContext().isUserSignin()) {
            ToastHelper.toast(this, R.string.mine_toast_login_first)
            AccountLoginActivity.launchLoginActivity(
                App.getContext(), Intent.FLAG_ACTIVITY_NEW_TASK
            )
            finish()
        }
        supportFragmentManager.beginTransaction()
            .replace(R.id.map_container_preview, gpxPreviewMapFragment).commitAllowingStateLoss()

        val intent = intent
        var str: String? = null
        intent?.apply {
            str = getStringExtra(PARAM_URI)
        }
        str?.apply {
            val uri = Uri.parse(this)
            viewModel.generateGpx(this@GPXImportActivity, uri)
        }
        initDropDownChooser()

        viewModel.actionLiveData.observe(this@GPXImportActivity) { contextAction ->
            ContextAction.handle(contextAction.action, object : ContextAction.ActionHandler {
                override fun onReFresh(str: String?) {
                }

                override fun onShowLoading(str: String?) {
                    showLoadingDialog(R.string.dialog_loading, true)
                }

                override fun onHideLoading(str: String?) {
                    dismissLoadingDialog()
                }

                override fun onFinish(str: String?) {
//                    finish()
                }
            })
        }

        viewModel.generateResult.observe(this@GPXImportActivity) {
            if (!it) {
                lifecycleScope.launch(Dispatchers.Main) {
                    snackLong(R.string.toast_import_failed, false)
                }
            } else {
                runOnUiThread {
                    val editText = binding.etTitle
                    val gpx = viewModel.getGpx().value
                    val metadata = gpx?.metadata?.desc ?: ""
                    editText.setText(metadata)
                }
                viewModel.requestGpxPreviewData()
            }
        }
        viewModel.getRouteBookPreviewLiveData()
            .observe(this@GPXImportActivity) { routeBookPreview ->
                binding.llPreView.visibility = View.VISIBLE
                val distanceUnit = DistanceUnit(java.lang.String.valueOf(routeBookPreview.dis))
                val altitudeUnit: AltitudeUnit =
                    AltitudeUnit(java.lang.String.valueOf(routeBookPreview.elevation_gain))
                binding.itemDistance.text = FormatterUtil.getFormatDistance(
                    distanceUnit.getValueBy(
                        "m"
                    )
                )
                val avg_gradle = routeBookPreview.avg_grade * 100
                binding.itemDistanceUnit.text = distanceUnit.getUnitString("m")
                binding.itemElevationGain.text = (altitudeUnit.getValueBy("m")).toString()
                binding.itemElevationGainUnit.text = altitudeUnit.getUnitString("m")
                binding.itemAvgGrade.text = java.lang.String.format("%.2f", avg_gradle)
            }
        viewModel.createFromGPXResultLiveData.observe(this) {
            if (it) {
                finish()
            }
        }

        t.btnSave.setOnClickListener {
            val text = binding.etTitle.text
            if (text.isNotEmpty()) {
                currentDropDownItem?.let {
                    val book = viewModel.getRouteBookPreviewLiveData().value
                    val dis = book?.dis ?: Utils.DOUBLE_EPSILON
                    viewModel.saveGpx(
                        binding.etTitle.text.toString(),
                        binding.etDesc.text.toString(),
                        it.value,
                        dis
                    )
                }
                return@setOnClickListener
            }
            val editText = binding.etTitle
            editText.clearAnimation()
            val translateAnimation = TranslateAnimation(
                1, 0.0f, 1, 0.0f, 1, 0.0f, 1, 0.5f
            )
            translateAnimation.duration = 100L
            translateAnimation.duration = 100L
            translateAnimation.repeatCount = 3
            translateAnimation.repeatMode = 2
            editText.startAnimation(translateAnimation)
        }
    }

    private fun initDropDownChooser() {
        val list = mutableListOf(
            DropDownItem(getString(R.string.cycling), R.drawable.ic_cycling_small, 3),
            DropDownItem(getString(R.string.running), R.drawable.ic_history_running, 1),
            DropDownItem(getString(R.string.walking), R.drawable.ic_walking_small, 1)
        )
        currentDropDownItem = list.first()
        refreshCurrentDropDownItem()
        val dropDownPopWindow =
            DropDownPopWindow(context, list, object : DropDownPopWindow.DropDownClickListener {
                override fun onMenuDismissed() {
                }

                override fun onMenuItemClicked(dropDownItem: DropDownItem) {
                    setCurrentDropDownItem(dropDownItem)
                    refreshCurrentDropDownItem()
                }
            })

        val linearLayout = binding.llType
        linearLayout.let {
            it.setOnClickListener {
                dropDownPopWindow.show(linearLayout, true)
            }
        }
    }

    private fun refreshCurrentDropDownItem() {
        currentDropDownItem?.let { current ->
            binding?.let {
                binding.imgType.let { img ->
                    {
                        img.setImageDrawable(
                            ContextCompat.getDrawable(
                                this@GPXImportActivity, current.icon
                            )
                        )
                    }
                }
                binding.tvType.text = current.text
            }
        }
    }

    private fun setCurrentDropDownItem(dropDownItem: DropDownItem?) {
        this.currentDropDownItem = dropDownItem
    }

    companion object {
        private const val PARAM_URI: String = "PARAM_URI"
        fun launch(context: Context, uri: Uri) {
            val intent = Intent(context, GPXImportActivity::class.java)
            intent.putExtra(PARAM_URI, uri.toString())
            context.startActivity(intent)
        }
    }
}